package tiles;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.io.Serializable;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;

import player.Player;
import etc.Mule;

/**
 * The tile class, which represents each space of land that can be occupied by a
 * player, extended by the types of Tiles.
 * 
 * @author Bradley
 */
public class Tile extends JButton implements Serializable {

    /** Auto-generated serial version ID. */
    private static final long serialVersionUID = -6945417819422205681L;
    private Player owner;
    private final int SIZE = 80;
    private final Dimension DIMENSION = new Dimension(SIZE, SIZE);
    private Icon icon;
    private boolean isTown;
    private int cost;
    private Mule mule;
    private String baseType;
    private String type;
    protected int[] productionRates; // food, energy, ore, crystite
    protected int defenseLevel;
    private String text;//the tooltip text
    private boolean hasWompus = false;
    private int upgradeLevel;
    private int upgradeDegrees;

    public Tile() {
	productionRates = new int[4];
	super.setPreferredSize(DIMENSION);
	super.setContentAreaFilled(true); // fills button with color
	super.setBorder(null);
	
	this.addMouseListener(new java.awt.event.MouseAdapter() {
	    public void mouseEntered(java.awt.event.MouseEvent evt) {
		if(owner == null && !hasWompus())
		    setBorder(new LineBorder(Color.BLACK, 2));
		
		if(owner == null && hasWompus())
		    setBorder(new LineBorder(Color.ORANGE, 5));
	    }
	    public void mouseExited(java.awt.event.MouseEvent evt) {
	        if(owner == null)
	            setBorder(null);
	    }
	    
	    public void mouseClicked(java.awt.event.MouseEvent evt){
		if(owner == null){
		    setBorder(null);
		}
	    }
	});
    }
    
    public Tile(int cost, String baseType, String type, boolean isTown) {
	this();
	this.cost = cost;
	this.baseType = baseType;
	this.type = type;
	this.isTown = isTown;
	this.icon = new ImageIcon(this.getClass().getResource(
		baseType + type + ".png"));
	this.defenseLevel=0;
	text = "";
	upgradeLevel = 0;
	setIcon(icon);
	updateTooltipText();
    }

    /**
     * Paints the tile on the panel.
     */
    @Override
    protected void paintComponent(Graphics g) {
	g.fillRect(0, 0, SIZE, SIZE);
	super.paintComponent(g);
    }
    
    public Player getOwner() {
	return owner;
    }
    
    public String getOwnerName(){
	return owner.getName();
    }
    
    public boolean hasOwner(){
	return getOwner()!=null;
    }

    public void setOwner(Player owner) {
	this.owner = owner;
	updateTooltipText();
    }
    
    public int getCost() {
	return cost;
    }

    /**
     * Gets the production rate of the tile, i.e. how quickly it produces new
     * resources.
     * 
     * @return The rate of production of resources.
     */

    public int getProductionRate(int type) {
	return productionRates[type] + upgradeLevel*upgradeDegrees;
    }

    public Icon getIcon() {
	return icon;
    }
    
    /**
     * Sets the player's border color.
     * 
     * @param color
     */
    public void playerBorder(Color color) {
	Border playerBorder = new LineBorder(color, 8);
	this.setBorder(playerBorder);
    }

    public boolean isTown() {
	return isTown;
    }

    public boolean hasMule() {
	return mule != null;
    }

    public int getMuleType() {
	return mule.getType();
	// 0 food; 1 energy; 2 ore; 3 crystite
    }
    
    public String getProductionType(){
	
	switch(getMuleType()){
	
	case 0: 
	    return "Food";
	case 1:
	    return "Energy";
	case 2:
	    return "Ore";
	case 3:
	    return "Crystite";
	default:
	    return "None";
	
	
	}
	
    }
    
    /**
     * add a mule to tile
     * @param mule
     */
    
    public void addMule(Mule mule) {
	this.mule = mule;
	icon = new ImageIcon(this.getClass().getResource(
		baseType + type + "-" + mule.getType() + ".png"));
	setIcon(icon);
	updateTooltipText();
    }
    
    public int getDefenseLevel(){
	return defenseLevel;
    }
    
    public void addDefense(){
	defenseLevel+=2;
	updateTooltipText();
    }
    
    public void upgrade(){
	upgradeLevel++;
	updateTooltipText();
    }
    
    public boolean decrementDefense(){
	if(defenseLevel>0){
	    defenseLevel--;
	    return true;
	}
	updateTooltipText();
	return false;
    }
    
    public void updateTooltipText(){
	text = "<html>";
	if(hasOwner()){
	    text += "Owner: "+this.getOwnerName()+"<br>";
	    text += "Level: "+upgradeLevel+"<br>";
	    text += "Defense Level: "+defenseLevel+"";
	    if(hasMule()){
		    text+="<br>";
		    text+= this.getProductionRate(this.getMuleType())+" "+this.getProductionType()+"/round";
		}
	}
	else{
	    text += "Owner: none";
	}

	text+="</html>";
	
	if(hasWompus()){
	    text = "WOMPUS!!!";
	}
	
	if(isTown()){
	    text = "Da Town";
	}
	
	super.setToolTipText(text);
    }
    
    public void removeMule(){
	mule = null;
	updateTooltipText();
	this.icon = new ImageIcon(this.getClass().getResource(
		baseType + type + ".png"));

    }
    
    public void attackDefend(int attackDefend){
	if(attackDefend == 1){//if being attacked
	    if(!decrementDefense()){
		if(hasMule())
		    removeMule();
		else
		    JOptionPane.showMessageDialog(null,
			    "This tile doesn't have a mule. You wasted your attack");
	    }
	    updateTooltipText();
	}
	
	if(attackDefend == 2){//if adding defense
	    addDefense();
	}
	
    }
    
    public void setWompus(boolean bool) {
    	hasWompus = bool;
    }
    
    public boolean hasWompus(){
    	return hasWompus;
    }
    
    public void setUpgradeDegree(int degree){
	this.upgradeDegrees = degree;
    }
}
    
    

